/*
 * ClientDaemon.h
 *
 *  Created on: Mar 25, 2012
 *      Author: Victor Nidens victornlj@gmail.com
 *		Author:	Mikhail S. Ananyevskiy, PhD, msaipme@yandex.ru
 *
 *	This file is part of Cloud Mechatronic Laboratory (CMLab) software.
 *
 *	Cloud Mechatronic Laboratory (CMLab) for CMLab is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU Lesser General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.
 *
 *	Cloud Mechatronic Laboratory (CMLab) software is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU Lesser General Public License for more details.
 *
 *	You should have received a copy of the GNU Lesser General Public License
 *	along with Cloud Mechatronic Laboratory (CMLab). If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef CLIENTDAEMON_H_
#define CLIENTDAEMON_H_

#include <arpa/inet.h>
#include <map>
#include <string>
#include <libusb-1.0/libusb.h>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <vector>
#include "protocol/protocol.h"
#include <mysql/mysql.h>

#define HashMap std::tr1::unordered_map
#define HashSet	std::tr1::unordered_set

using namespace std;

typedef struct {
	string	name;
	uint8	ip[4];
	string	serverIP;
	int		tcpPort;
	int		udpPort;
	uint8	legoDevicesCount;
	bool	savePacketStat;
	string	dbHost;
	int		dbPort;
	string	dbUser;
	string	dbUserPassword;
	string	dbName;
	string	dbTable;
} ClientConfig;

class ClientDaemon {

protected:

	ClientConfig config;

	Source sourceInfo;

	struct sockaddr_in tcpSocket;
	struct sockaddr_in udpSocket;

	int tcpSocketFD;
	int udpSocketFD;

	HashMap<string, libusb_device_handle*> connectedDevices;
	vector<ExchangePacket> receivedQueue;

	MYSQL *dbConnection;

	void daemonize();
	void mainloop();
	void commit();

	int tcpConnect();
	int tcpPing();
	int udpPing();

	void makeNonblockingFD(int fd);

	void handleReceivedPacket();
	void keepAliveDevices();
	void announceDevices();
	int autoInitSensor(ExchangePacket *request, libusb_device_handle **deviceHandle);

	int initDBStorage();
	void savePacketStat(ExchangePacket *packet);

	static void sighandler(int signum);

public:
	ClientDaemon(ClientConfig conf);
	void exec();

};


#endif /* CLIENTDAEMON_H_ */
